<template>
  <ControlWrap>
    <div class="mx-auto h-full bg-white rounded-lg shadow-sm">
      <!-- 顶部操作栏 -->
      <div
        style="height: 76px"
        class="p-4 border-b flex items-center justify-between"
      >
        <div class="flex gap-3">
          <button
            class="!rounded-button bg-blue-600 text-white px-4 py-2 flex items-center gap-2 hover:bg-blue-700 whitespace-nowrap"
            @click="addRootDirectory(ruleFormRef)"
          >
            <i class="fas fa-plus-circle"></i>
            添加菜单
          </button>
          <button
            class="!rounded-button border border-gray-300 px-4 py-2 flex items-center gap-2 hover:bg-gray-50 whitespace-nowrap"
            @click="expandRowKeys = allKeys"
          >
            <i class="fas fa-chevron-down"></i>
            展开全部
          </button>
          <button
            class="!rounded-button border border-gray-300 px-4 py-2 flex items-center gap-2 hover:bg-gray-50 whitespace-nowrap"
            @click="expandRowKeys = []"
          >
            <i class="fas fa-chevron-up"></i>
            折叠全部
          </button>
        </div>
      </div>
      <div style="height: calc(100% - 76px)" class="">
        <el-table
          :show-header="true"
          height="100%"
          :data="previewMenu"
          style="width: 100%; margin-bottom: 20px"
          row-key="menu_id"
          :border="false"
          :default-expand-all="false"
          :expand-row-keys="expandRowKeys"
          :row-style="setRowStyle"
          @expand-change="expandChange"
        >
          <el-table-column
            prop="menu_name"
            fixed="left"
            min-width="180px"
            label="菜单名称"
          />
          <el-table-column prop="directory" width="80px" label="菜单类型">
            <template #default="{ row }">
              <el-tag type="success" effect="dark" v-if="row.directory == 0"
                >目录</el-tag
              >
              <el-tag effect="dark" v-else>菜单</el-tag>
            </template>
          </el-table-column>
          <el-table-column
            prop="icon"
            align="center"
            :show-overflow-tooltip="true"
            width="100px"
            label="菜单图标"
          >
            <template #default="{ row }">
              <span
                style="display: inline-block; width: 20px; height: 20px"
                v-icon="row.icon"
              ></span>
            </template>
          </el-table-column>
          <el-table-column
            prop="component_name"
            align="center"
            :show-overflow-tooltip="true"
            width="100px"
            label="组件名称"
          />
          <el-table-column
            prop="component_src"
            align="center"
            :show-overflow-tooltip="true"
            width="100px"
            label="组件路径"
          />
          <el-table-column
            prop="self_src"
            align="center"
            :show-overflow-tooltip="true"
            width="100px"
            label="菜单地址"
          />
          <el-table-column
            prop="weight"
            align="center"
            width="100px"
            label="菜单排序"
          />
          <el-table-column
            prop="keepalive"
            align="center"
            width="100px"
            label="菜单缓存"
          >
            <template #default="{ row }">
              {{
                row.directory == 1
                  ? row.keepalive == 0
                    ? "缓存"
                    : "不缓存"
                  : ""
              }}
            </template>
          </el-table-column>
          <el-table-column
            fixed="right"
            align="center"
            width="180px"
            label="操作"
          >
            <template #header>
              <el-input
                v-model="search"
                size="small"
                clearable
                placeholder="搜索一级菜单名称"
              />
            </template>
            <template #default="{ row }">
              <el-button type="primary" @click="editMenuData(row)"
              class="mr-1"
                >编辑</el-button
              >
              <el-button type="danger" @click="delMenuData(row)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
  </ControlWrap>
  <!-- 表单 -->
  <CustomModal
    v-model="dialogFormVisible"
    :draggable="true"
    :loading="loading"
    :title="formTitle"
    width="500"
    height="400px"
    @confirm="confirm($event, ruleFormRef)"
    @close="close"
    @open="open"
  >
    <template #default>
      <el-form
        :model="form"
        ref="ruleFormRef"
        :rules="rules"
        label-width="90px"
      >
        <el-form-item label="上级菜单:" prop="parent_id">
          <el-tree-select
            v-model="form.parent_id"
            :data="seletMenuOption"
            check-strictly
            :render-after-expand="false"
          />
        </el-form-item>
        <el-form-item label="菜单类型:" prop="directory">
          <el-select
            v-model="form.directory"
            placeholder="Please select a zone"
          >
            <el-option label="目录" :value="0" />
            <el-option label="菜单" :value="1" />
          </el-select>
        </el-form-item>
        <el-form-item label="菜单名称:" prop="menu_name">
          <el-input v-model="form.menu_name" autocomplete="off" />
        </el-form-item>
        <el-form-item label="菜单图标:" prop="icon">
          <el-select
            style="width: 240px"
            v-model="form.icon"
            placeholder="请选择菜单图标"
          >
            <el-option
              v-for="(item, index) in IconOption"
              :label="item"
              :value="item"
            >
              <div
                style="
                  display: flex;
                  flex-wrap: nowrap;
                  align-items: center;
                  justify-content: space-between;
                "
              >
                <span style="width: 20px; height: 20px" v-icon="item"></span>
                <span>{{ item }}</span>
              </div>
            </el-option>
          </el-select>
          <div
            v-if="form.icon"
            style="width: 20px; height: 20px; margin-left: auto"
            v-icon="form.icon"
          ></div>
        </el-form-item>
        <el-form-item label="路由地址:" prop="router_src">
          <el-input
            v-model.trim="form.router_src"
            placeholder="userList,一级加/,二级去掉/"
            autocomplete="off"
          />
        </el-form-item>
        <el-form-item
          :rules="[
            { required: true, message: '请输入组件路径', trigger: 'blur' },
          ]"
          v-if="form.directory"
          label="组件路径:"
          prop="component_src"
        >
          <el-input
            v-model.trim="form.component_src"
            placeholder="view目录下的例:userManagement/userList/index"
            autocomplete="off"
          />
        </el-form-item>
        <el-form-item
          :rules="[
            { required: true, message: '请输入组件名称', trigger: 'blur' },
          ]"
          v-if="form.directory"
          label="组件名称:"
          prop="component_name"
        >
          <el-input
            v-model.trim="form.component_name"
            placeholder="例:userList"
            autocomplete="off"
          />
        </el-form-item>
        <el-form-item label="菜单权重:" prop="weight">
          <el-input-number
            v-model="form.weight"
            :precision="0"
            :min="0"
            :max="10000"
          />
        </el-form-item>
        <el-form-item label="是否隐藏:" prop="hidden">
          <el-select v-model="form.hidden" placeholder="Please select a zone">
            <el-option label="显示" :value="0" />
            <el-option label="隐藏" :value="1" />
          </el-select>
        </el-form-item>
        <el-form-item v-if="form.directory" label="是否缓存:" prop="keepalive">
          <el-select
            v-model="form.keepalive"
            placeholder="Please select a zone"
          >
            <el-option label="缓存" :value="0" />
            <el-option label="不缓存" :value="1" />
          </el-select>
        </el-form-item>
      </el-form>
    </template>
  </CustomModal>
</template>
<script setup>
import { ref, reactive, computed, getCurrentInstance } from "vue";
import { addMenu, editMenu, deleteMenu, getMenuList } from "@/api/meun";
import { useUserStore } from "@/store/user";
import { storeToRefs } from "pinia";
import Icons from "@/util/elementPlusIcon";
import CustomModal from "@/components/customModal/index.vue";
import _ from "lodash";
import { ElMessage } from "element-plus";
const { proxy } = getCurrentInstance();
const user = useUserStore();
const IconOption = ref(Icons); //图标备选数据
const { dirMenu, latestMenuList } = storeToRefs(user);
const { getLatestMenuList } = user;
const search = ref("");
const previewMenu = computed(() => {
  const menu = _.cloneDeep(latestMenuList.value)
    .slice(1)
    .filter((item) => {
      return (
        !search.value ||
        item.menu_name.toLowerCase().includes(search.value.toLowerCase())
      );
    });
  return menu.map((item, index) => {
    if (index % 2 != 0) {
      item.isEven = true;
    }
    return item;
  });
});
const editRowData = ref({}); //编辑行数据
const seletMenuOption = computed(() => {
  const deleteSelfDir = (val) => {
    // 过滤掉当前编辑的菜单
    return val
      .filter((item) => item.value !== editRowData.value.menu_id)
      .map((item) => {
        if (item.children) {
          // 递归过滤子菜单
          item.children = deleteSelfDir(item.children);
        }
        return item;
      });
  };
  // 克隆原菜单数据并进行过滤
  return deleteSelfDir(_.cloneDeep(dirMenu.value));
});
const handleType = ref(1); //操作类型

const formTitle = computed(() => {
  return handleType.value == 1 ? "添加菜单" : "编辑菜单";
});
const loading = ref(false);
const dialogFormVisible = ref(false);
const form = reactive({
  parent_id: "-1",
  hidden: 0,
  icon: "",
  keepalive: 0,
  directory: 0,
  weight: 0,
  component_name: "",
  component_src: "",
  menu_name: "",
  router_src: "",
});
const ruleFormRef = ref();
const rules = reactive({
  icon: [
    {
      required: true,
      message: "请选择菜单图标",
      trigger: "change",
    },
  ],
  menu_name: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
  router_src: [{ required: true, message: "请输入路由地址", trigger: "blur" }],
});
//关闭弹窗重置表单
const close = () => {
  editRowData.value = {};
  form.directory = 0;
  form.component_name = "";
  form.component_src = "";
  form.hidden = 0;
  form.icon = "";
  form.keepalive = 0;
  form.menu_name = "";
  form.parent_id = "-1";
  form.weight = 0;
  form.router_src = "";
};
//打开弹窗前清楚校验
const open = () => {
  ruleFormRef.value.clearValidate();
};
//添加菜单
const addRootDirectory = (form1) => {
  handleType.value = 1;
  dialogFormVisible.value = true;
};
//编辑菜单
const editMenuData = (row) => {
  editRowData.value = _.cloneDeep(row);
  handleType.value = 2;
  dialogFormVisible.value = true;
  form.directory = row.directory;
  form.component_name = row.component_name;
  form.component_src = row.component_src;
  form.hidden = row.hidden;
  form.icon = row.icon;
  form.keepalive = row.keepalive;
  form.menu_name = row.menu_name;
  form.parent_id = row.parent_id ? row.parent_id : "-1";
  form.weight = row.weight;
  form.router_src = row.self_src;
};
//删除菜单
const delMenuData = (row) => {
  if (row.children.length > 0) {
    ElMessage.error("存在子菜单无法删除!");
    return;
  }
  proxy.$gf.tip(
    async (val) => {
      if (val) {
        await deleteMenu({
          menuId: row.menu_id,
          successMsg: true,
          errorMsg: true,
        });
        await getLatestMenuList();
      }
    },
    { content: "确定要删除该菜单吗?" }
  );
};
//提交
const confirm = async (e, formEl) => {
  if (!formEl) return;
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      console.log("submit!", form, fields);
      loading.value = true;
      try {
        const startsWithSlash = (path) => {
          const regex = /^\//;
          return regex.test(path);
        };
        //添加
        if (handleType.value == 1) {
          if (form.parent_id != "-1" && startsWithSlash(form.router_src)) {
            ElMessage.error("子菜单不能以/开头!");
            return;
          }
          if (form.parent_id == "-1" && !startsWithSlash(form.router_src)) {
            ElMessage.error("一级菜单必须以/开头!");
            return;
          }
          await addMenu({
            menuName: form.menu_name,
            weight: form.weight,
            directory: form.directory,
            componentSrc: form.directory == 1 ? form.component_src : "",
            componentName: form.directory == 1 ? form.component_name : "",
            keepAlive: form.keepalive,
            hidden: form.hidden,
            icon: form.icon,
            parentId: form.parent_id == "-1" ? "" : form.parent_id,
            routerSrc: form.router_src,
            successMsg: true,
            errorMsg: true,
          });
          await getLatestMenuList();
          return;
        }
        //编辑目录
        if (
          editRowData.value.directory == 0 &&
          form.parent_id != "-1" &&
          editRowData.value.children.length > 0
        ) {
          ElMessage.error("存在子菜单无法切换菜单位置!");
          return;
        }
        if (form.parent_id != "-1" && startsWithSlash(form.router_src)) {
          ElMessage.error("子菜单不能以/开头!");
          return;
        }
        if (form.parent_id == "-1" && !startsWithSlash(form.router_src)) {
          ElMessage.error("一级菜单必须以/开头!");
          return;
        }
        await editMenu({
          menuId: editRowData.value.menu_id,
          menuName: form.menu_name,
          weight: form.weight,
          directory: form.directory,
          componentSrc: form.directory == 1 ? form.component_src : "",
          componentName: form.directory == 1 ? form.component_name : "",
          keepAlive: form.keepalive,
          hidden: form.hidden,
          icon: form.icon,
          parentId: form.parent_id == "-1" ? "" : form.parent_id,
          routerSrc: form.router_src,
          successMsg: true,
          errorMsg: true,
        });
        await getLatestMenuList();
      } catch (error) {
        console.log(error, "hahha");
      } finally {
        loading.value = false;
        dialogFormVisible.value = false;
      }
    } else {
      console.log("error submit!", fields);
    }
  });
};

//菜单展示相关
const expandRowKeys = ref([]);
//展开全部菜单
const allKeys = computed(() => {
  const countItems = (items) => {
    let count = items.map((child) => String(child.menu_id));
    items.forEach((item) => {
      if (item.children && item.children.length) {
        count.push(...countItems(item.children));
      }
    });
    return count;
  };
  return countItems(previewMenu.value);
});
//打开菜单
const expandChange = (e, expanded) => {
  if (!expanded) {
    const index = expandRowKeys.value.findIndex((item) => item == e.id);
    if (index != -1) {
      expandRowKeys.value.splice(index, 1);
    }
    return;
  }
  expandRowKeys.value.push(e.id);
};
const setRowStyle = (e) => {
  return !e.row.parent_id && e.row.isEven
    ? {
        background: "rgb(237 238 226)",
      }
    : {};
};
</script>
<style scoped>
.directory-item {
  position: relative;
}

.directory-item:hover .opacity-0 {
  opacity: 1;
}

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
</style>
